package me.wangcai.trafficpoliceai.config.component;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtTokenUtils {
     private static final String CLATM_KEY_USERNAME="sub";
     private static  final String CLAIM_KEY_CREATED="created";
     @Value("${jwt.secret}")
     private String secret;
     @Value("${jwt.expiration}")
     private Long expiration;
     public String generateToken(UserDetails userDetails)
     {
          Map<String,Object> claims=new HashMap<>();
          claims.put(CLATM_KEY_USERNAME,userDetails.getUsername());
          claims.put(CLAIM_KEY_CREATED,new Date());
          return generateToken(claims);

     }
     private String generateToken(Map<String,Object> claims){
          return Jwts.builder()
                  .setClaims(claims)
                  .setExpiration(generateExpirationDate())
                  .signWith(SignatureAlgorithm.HS256,secret)
                  .compact();
     }

     private Date generateExpirationDate() {
          return new Date(System.currentTimeMillis()+expiration*1000);//返回一个long类型的值，该值表示的是当前时间与1970年1月1日0时0分0秒之间的时间差
     }
     public String getUserNameFromToken(String token){
          String username;
          try {
               Claims claims=getClaimsFormToken(token);
               username=claims.getSubject();//获取当前登录用户的信息
          } catch (Exception e) {
              username=null;
          }
         return username;
     }

     private Claims getClaimsFormToken(String token)
     {
          Claims claims=null;
          try {
                claims=Jwts.parser()
                       .setSigningKey(secret)
                       .parseClaimsJws(token)
                       .getBody();
          } catch (Exception e) {
               e.printStackTrace();
          }
          return claims;
     }
     public boolean validateToken(String token,UserDetails userDetails)
     {
          String username=getUserNameFromToken(token);
          return username.equals(userDetails.getUsername())&& !isTokenExpired(token);
     }

     private boolean isTokenExpired(String token) {
        Date expirDate=getExpiredDateFromToken(token);
        return expirDate.before(new Date());
     }

     private Date getExpiredDateFromToken(String token) {
          Claims claims=getClaimsFormToken(token);
          return claims.getExpiration();
     }
     public boolean canRefresh(String token)
     {
          return !isTokenExpired(token);
     }
     public String refreshToken(String token){
          Claims claims=getClaimsFormToken(token);
          claims.put(CLAIM_KEY_CREATED,new Date());
          return  generateToken(claims);
     }
}
